package cn.leaf.uc.service.service.impl;

import cn.hutool.core.convert.Convert;
import cn.leaf.common.constant.Oauth2Constant;
import cn.leaf.common.exception.TokenException;
import cn.leaf.security.userdetails.LeafUser;
import cn.leaf.security.userdetails.LeafUserDetailsService;
import cn.leaf.uc.api.dto.UserInfo;
import cn.leaf.uc.api.entity.PermissionEntity;
import cn.leaf.uc.api.entity.RolePermissionEntity;
import cn.leaf.uc.api.entity.UserEntity;
import cn.leaf.uc.api.entity.UserRoleEntity;
import cn.leaf.uc.api.mapper.PermissionMapper;
import cn.leaf.uc.api.mapper.RolePermissionMapper;
import cn.leaf.uc.api.mapper.UserMapper;
import cn.leaf.uc.api.mapper.UserRoleMapper;
import cn.leaf.uc.service.enums.LoginType;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 *
 * description: 用户详情实现类
 *
 * @author twinkle leaf
 * @version v1.0.0
 * @since 2021-11-07 23:55:16
 * slogan: There are no two identical leaves in the world.
 *
 */
@Slf4j
@Service
public class UserDetailsServiceImpl implements LeafUserDetailsService {

	public static final String ENABLE = "0";
	public static final String DISABLE = "1";

	@Resource
	private UserMapper userMapper;
	@Resource
	private UserRoleMapper userRoleMapper;
	@Resource
	private RolePermissionMapper rolePermissionMapper;
	@Resource
	private PermissionMapper permissionMapper;

	@Override
	public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
		UserInfo userInfo = getUserByUserName(userName);
		if (userInfo == null) {
			throw new TokenException("该用户：" + userName + "不存在");
		}
		userInfo.setType(Oauth2Constant.LOGIN_USERNAME_TYPE);
		userInfo.setUserName(userName);
		return getUserDetails(userInfo);

	}

//	@Override
//	public UserDetails loadUserByMobile(String mobile) throws UsernameNotFoundException {
//		UserInfo userInfo = sysUserProvider.getUserByMobile(mobile).getData();
//		if (userInfo == null) {
//			throw new TokenException("该用户：" + mobile + "不存在");
//		}
//		userInfo.setType(Oauth2Constant.LOGIN_MOBILE_TYPE);
//		userInfo.setUserName(mobile);
//		return getUserDetails(userInfo);
//	}

//	@Override
//	public UserDetails loadUserBySocial(String openId) throws UsernameNotFoundException {
//		String userName = "admin";
//		UserInfo userInfo = sysUserProvider.getUserByUserName(userName).getData();
//		if (userInfo == null) {
//			throw new TokenException("该用户：" + userName + "不存在");
//		}
//		userInfo.setType(Oauth2Constant.LOGIN_USERNAME_TYPE);
//		userInfo.setUserName(userName);
//		return getUserDetails(userInfo);
//	}
//
//

	private UserDetails getUserDetails(UserInfo userInfo) {
		if (ObjectUtils.isEmpty(userInfo)) {
			log.info("该用户：{} 不存在！", userInfo.getUserName());
			throw new TokenException("该用户：" + userInfo.getUserName() + "不存在");
		} else if (DISABLE.equals(userInfo.getUserEntity().getStatus())) {
			log.info("该用户：{} 已被停用!", userInfo.getUserName());
			throw new TokenException("对不起，您的账号：" + userInfo.getUserName() + " 已停用");
		}
		UserEntity user = userInfo.getUserEntity();
		log.info("用户名：{}", userInfo.getUserEntity().getAccount());

		List<GrantedAuthority> authorityList = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(userInfo.getRoleIds())) {
			authorityList
					= AuthorityUtils.createAuthorityList(Convert.toStrArray(userInfo.getRoleIds()));
			log.info("authorities: {}", authorityList);
		}
		return new LeafUser(user.getId(), userInfo.getType(), user.getDepartmentId(), user.getRoleId(), user.getPhone(), user.getAvatar(),
				user.getTenantId(), userInfo.getUserName(), user.getPassword(), ENABLE.equals(user.getStatus()),
				true, true, true,
				authorityList);
	}

	/**
	 * 根据用户名获取用户信息
	 * @param userName 用户名
	 * @return {@link UserInfo}
	 */
	private UserInfo getUserByUserName(String userName) {


		// 1.根据用户名获取用户信息
		UserEntity entity = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().
				eq(UserEntity::getAccount, userName));

		if (Optional.ofNullable(entity).isPresent()) {

			UserInfo userInfo = UserInfo.builder()
					.userEntity(entity)
					.userName(entity.getAccount())
					.type(LoginType.USERNAME.getType())
					.build();
			// 2.获取角色id
			List<UserRoleEntity> userRoleEntityList = userRoleMapper.selectList(new LambdaQueryWrapper<UserRoleEntity>().eq(UserRoleEntity::getUserId, entity.getId()));

			if (CollectionUtils.isNotEmpty(userRoleEntityList)) {
				List<Long> roleIds = userRoleEntityList.parallelStream().map(UserRoleEntity::getRoleId).collect(Collectors.toList());
				userInfo.setRoleIds(roleIds);

				// 3.获取权限id集合
				List<RolePermissionEntity> rolePermissionEntityList = rolePermissionMapper.selectList(new LambdaQueryWrapper<RolePermissionEntity>()
						.in(RolePermissionEntity::getRoleId, roleIds));

				if (CollectionUtils.isNotEmpty(rolePermissionEntityList)) {
					List<Long> permissionIds = rolePermissionEntityList.parallelStream().map(RolePermissionEntity::getPermissionId).collect(Collectors.toList());
					List<PermissionEntity> permissionEntityList = permissionMapper.selectList(new LambdaQueryWrapper<PermissionEntity>()
							.in(PermissionEntity::getId, permissionIds));

					// 4.获取权限名称
					List<String> permissionList = permissionEntityList.parallelStream().map(PermissionEntity::getName).collect(Collectors.toList());
					userInfo.setPermissions(permissionList);
				}
			}
			return userInfo;
		}
		return null;
	}
}
